package com.book.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.book.core.domain.SysMenu;
import com.book.core.domain.SysRole;
import com.book.core.domain.SysRoleMenu;
import com.book.core.dto.SysRoleSaveDTO;
import com.book.core.enums.CommonStatus;
import com.book.core.enums.MenuType;
import com.book.core.query.SysMenuQuery;
import com.book.core.util.LoginUserUtil;
import com.book.core.vo.BookCategoryVO;
import com.book.core.vo.SysMenuVO;
import com.book.repository.SysMenuMapper;
import com.book.service.SysMenuService;
import com.book.service.SysRoleMenuService;
import com.book.service.SysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hongmizfb
 * @description 针对表【sys_menu】的数据库操作Service实现
 * @createDate 2025-05-11 16:30:25
 */
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>
        implements SysMenuService {
    private final SysRoleMenuService sysRoleMenuService;
    private final SysRoleService sysRoleService;

    @Override
    public List<SysMenuVO> getMenuTreeList(SysMenuQuery query) {
//        考虑到菜单数据较少，暂不实现分页
        String keyword = query.getKeyword();
        Integer status = query.getStatus();
        List<SysMenuVO> allList = lambdaQuery()
                .eq(status != null && status != -1, SysMenu::getStatus, status)
                .like(StrUtil.isNotBlank(keyword), SysMenu::getMenuName, keyword)
                .or().eq(StrUtil.isNotBlank(keyword),SysMenu::getMenuCode, keyword)
                .list().stream().map(sysMenu -> {
                    SysMenuVO sysMenuVO = new SysMenuVO();
                    BeanUtils.copyProperties(sysMenu, sysMenuVO);
                    return sysMenuVO;
                }).collect(Collectors.toList());
        List<SysMenuVO> parentList = allList.stream().filter(sysMenuVO -> sysMenuVO.getParentId() == 0).collect(Collectors.toList());
        return convertToTree(parentList, allList);
    }

    @Override
    public List<SysMenuVO> getParentMenuList() {
        List<SysMenuVO> allList = lambdaQuery().ne(SysMenu::getType, MenuType.BUTTON.getCode()).list().stream().map(sysMenu -> {
            SysMenuVO sysMenuVO = new SysMenuVO();
            BeanUtils.copyProperties(sysMenu, sysMenuVO);
            return sysMenuVO;
        }).collect(Collectors.toList());
        List<SysMenuVO> parentList = allList.stream().filter(sysMenuVO -> sysMenuVO.getParentId() == 0).collect(Collectors.toList());
        return convertToTree(parentList, allList);
    }

    @Override
    public List<String> getMenuCodeListByUserId(Integer userId) {
        List<Integer> collect = sysRoleService.getRoleListByUserId(userId).stream().map(SysRole::getRoleId).collect(Collectors.toList());
        List<Integer> sysRoleMenuList = sysRoleMenuService.lambdaQuery().in(SysRoleMenu::getRoleId, collect).list().stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        return lambdaQuery().in(SysMenu::getMenuId, sysRoleMenuList).eq(SysMenu::getStatus, CommonStatus.NORMAL.getCode()).list().stream().map(SysMenu::getMenuCode).collect(Collectors.toList());
    }

    @Override
    public List<SysMenu> getMenuListByRoleId(Integer roleId) {
        SysRole byId = sysRoleService.getById(roleId);
//        超级管理员则返回所有权限
        if ("admin".equals(byId.getRoleCode())) {
            return lambdaQuery().list();
        }
        List<Integer> collect = sysRoleMenuService.lambdaQuery().eq(SysRoleMenu::getRoleId, roleId).list().stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)) {
            return null;
        }
        return lambdaQuery().in(SysMenu::getMenuId, collect).list();
    }

    @Override
    public void saveMenuRole(SysRoleSaveDTO sysMenuRoleDTO) {
        if (sysMenuRoleDTO.getRoleId() == null) {
            sysMenuRoleDTO.setCreateTime(LocalDateTime.now());
            sysMenuRoleDTO.setCreatorId(LoginUserUtil.getUserId());
            sysRoleService.save(sysMenuRoleDTO);
        } else {
            sysMenuRoleDTO.setUpdateTime(LocalDateTime.now());
            sysRoleService.updateById(sysMenuRoleDTO);
        }
        List<Integer> menuIds = sysMenuRoleDTO.getMenuIds();
        if (CollUtil.isNotEmpty(menuIds)) {
//            删除之前的菜单信息,然后再新增
            sysRoleMenuService.lambdaUpdate().eq(SysRoleMenu::getRoleId, sysMenuRoleDTO.getRoleId()).remove();
            for (Integer menuId : menuIds) {
                sysRoleMenuService.save(new SysRoleMenu(sysMenuRoleDTO.getRoleId(), menuId));
            }
        }
    }

    public List<SysMenuVO> convertToTree(List<SysMenuVO> parentList, List<SysMenuVO> allList) {
        parentList.forEach(parent -> {
            List<SysMenuVO> children = allList.stream().filter(child -> child.getParentId().equals(parent.getMenuId())).collect(Collectors.toList());
            convertToTree(children, allList);
            parent.setChildren(children);
        });
        return parentList;
    }
}




